<!DOCTYPE HTML>
<html lang="zh-CN">


<head>
    <meta charset="utf-8">
    <meta name="keywords" content="ant-design简介, 凌">
    <meta name="description" content="">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <!-- Global site tag (gtag.js) - Google Analytics -->


    <title>ant-design简介 | 凌</title>
    <link rel="icon" type="image/png" href="/blog/favicon.png">

    <link rel="stylesheet" type="text/css" href="https://sky508.gitee.io/blog/libs/awesome/css/all.css">
    <link rel="stylesheet" type="text/css" href="https://sky508.gitee.io/blog/libs/materialize/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="https://sky508.gitee.io/blog/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="https://sky508.gitee.io/blog/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="https://sky508.gitee.io/blog/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="/blog/css/matery.css">
    <link rel="stylesheet" type="text/css" href="/blog/css/my.css">

    <script src="https://sky508.gitee.io/blog/libs/jquery/jquery.min.js"></script>

<meta name="generator" content="Hexo 4.2.0"><link rel="stylesheet" href="/blog/css/prism.css" type="text/css">
<link rel="stylesheet" href="/blog/css/prism-line-numbers.css" type="text/css"></head>


<body>
    <header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper container">
            <div class="brand-logo">
                <a href="/blog/" class="waves-effect waves-light">
                    
                    <img src="" data-original="https://glh508-blog-img.oss-cn-beijing.aliyuncs.com/banner/logo.png" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">凌</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/blog/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>首页</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/blog/tags" class="waves-effect waves-light">
      
      <i class="fas fa-tags" style="zoom: 0.6;"></i>
      
      <span>标签</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/blog/categories" class="waves-effect waves-light">
      
      <i class="fas fa-bookmark" style="zoom: 0.6;"></i>
      
      <span>分类</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/blog/archives" class="waves-effect waves-light">
      
      <i class="fas fa-archive" style="zoom: 0.6;"></i>
      
      <span>归档</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/blog/contact" class="waves-effect waves-light">
      
      <i class="fas fa-comments" style="zoom: 0.6;"></i>
      
      <span>联系</span>
    </a>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="搜索" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>


<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="" data-original="https://glh508-blog-img.oss-cn-beijing.aliyuncs.com/banner/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">凌</div>
        <div class="logo-desc">
            
            Never really desperate, only the lost of the soul.
            
        </div>
    </div>

    

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/blog/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			首页
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/blog/tags" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-tags"></i>
			
			标签
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/blog/categories" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-bookmark"></i>
			
			分类
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/blog/archives" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-archive"></i>
			
			归档
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/blog/contact" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-comments"></i>
			
			联系
		</a>
          
        </li>
        
        
    </ul>
</div>


        </div>

        
    </nav>

</header>

    



<div class="bg-cover pd-header post-cover" style="background-image: url('https://glh508-blog-img.oss-cn-beijing.aliyuncs.com/img/17.jpg')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title">ant-design简介</h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="post-container content">

    
    <link rel="stylesheet" href="https://sky508.gitee.io/blog/libs/tocbot/tocbot.css">
<style>
    #articleContent h1::before,
    #articleContent h2::before,
    #articleContent h3::before,
    #articleContent h4::before,
    #articleContent h5::before,
    #articleContent h6::before {
        display: block;
        content: " ";
        height: 100px;
        margin-top: -100px;
        visibility: hidden;
    }

    #articleContent :focus {
        outline: none;
    }

    .toc-fixed {
        position: fixed;
        top: 64px;
    }

    .toc-widget {
        width: 345px;
        padding-left: 20px;
    }

    .toc-widget .toc-title {
        margin: 35px 0 15px 0;
        padding-left: 17px;
        font-size: 1.5rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    .toc-widget ol {
        padding: 0;
        list-style: none;
    }

    #toc-content {
        height: calc(100vh - 250px);
        overflow: auto;
    }

    #toc-content ol {
        padding-left: 10px;
    }

    #toc-content ol li {
        padding-left: 10px;
    }

    #toc-content .toc-link:hover {
        color: #42b983;
        font-weight: 700;
        text-decoration: underline;
    }

    #toc-content .toc-link::before {
        background-color: transparent;
        max-height: 25px;

        position: absolute;
        right: 23.5vw;
        display: block;
    }

    #toc-content .is-active-link {
        color: #42b983;
    }

    #floating-toc-btn {
        position: fixed;
        right: 15px;
        bottom: 76px;
        padding-top: 15px;
        margin-bottom: 0;
        z-index: 998;
    }

    #floating-toc-btn .btn-floating {
        width: 48px;
        height: 48px;
    }

    #floating-toc-btn .btn-floating i {
        line-height: 48px;
        font-size: 1.4rem;
    }
</style>
<div class="row">
    <div id="main-content" class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                    <div class="article-tag">
                        
                            <a href="/blog/tags/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6/">
                                <span class="chip bg-color">前端框架</span>
                            </a>
                        
                    </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                    <div class="post-cate">
                        <i class="fas fa-bookmark fa-fw icon-category"></i>
                        
                            <a href="/blog/categories/%E6%8A%80%E5%B7%A7%E4%BB%8B%E7%BB%8D/" class="post-category">
                                技巧介绍
                            </a>
                        
                    </div>
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>发布日期:&nbsp;&nbsp;
                    2020-08-24
                </div>
                

                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-check fa-fw"></i>更新日期:&nbsp;&nbsp;
                    2020-08-24
                </div>
                

                

                

                
                    <div id="busuanzi_container_page_pv" class="info-break-policy">
                        <i class="far fa-eye fa-fw"></i>阅读次数:&nbsp;&nbsp;
                        <span id="busuanzi_value_page_pv"></span>
                    </div>
				
            </div>
        </div>
        <hr class="clearfix">
        <div class="card-content article-card-content">
            <div id="articleContent">
                <h2 id="一、简介"><a href="#一、简介" class="headerlink" title="一、简介"></a>一、简介</h2><p>由阿里巴巴开发的Ant Design是一种<a href="http://www.elecfans.com/tags/javascript/" target="_blank" rel="noopener">Javascript</a>库类型的ReactJS组件库。通过将屏幕区域分为24列网格，它增加了用户对于可见区域的自定义能力。同时，它通过各种填充（filled）和轮廓（outlined）图标，来满足不同的应用程序的要求。</p>
<p>其实Ant Design 是一个 ui框架，和 bootstrap 一样是ui框架。里面的组件很完善，开发中后台系统非常方便。分别基于react、vue、angular框架，各自开发了一套 Ant Design 的UI框架。</p>
<p><img src="" data-original="https://glh508-blog-img.oss-cn-beijing.aliyuncs.com/image-20200824110116223.png" alt=""></p>
<hr>
<h2 id="二、特性："><a href="#二、特性：" class="headerlink" title="二、特性："></a>二、特性：</h2><ul>
<li>提炼自企业级中后台产品的交互语言和视觉风格。</li>
<li>开箱即用的高质量 React 组件。</li>
<li>使用 TypeScript 开发，提供完整的类型定义文件。</li>
<li>全链路开发和设计工具体系。</li>
<li>数十个国际化语言支持。</li>
<li>深入每个细节的主题定制能力。</li>
<li>其中ant-design-vue共享<a href="http://ant-design.gitee.io/docs/spec/introduce-cn" target="_blank" rel="noopener">Ant Design of React</a>设计工具体系</li>
</ul>
<hr>
<h2 id="三、使用情况统计："><a href="#三、使用情况统计：" class="headerlink" title="三、使用情况统计："></a>三、使用情况统计：</h2><table>
<thead>
<tr>
<th>框架名称</th>
<th>组件数量</th>
<th>单元测试率</th>
<th>admin项目</th>
<th>维护团队</th>
<th>GitHub Star数（2020/8/20）</th>
<th>原型设计素材</th>
</tr>
</thead>
<tbody><tr>
<td>Element UI</td>
<td>56</td>
<td>81%</td>
<td>vue-element-admin</td>
<td>饿了么</td>
<td>41.9K</td>
<td>Axure、Sketch</td>
</tr>
<tr>
<td>Ant Design Vue</td>
<td>62</td>
<td>87%</td>
<td>Ant Design Pro</td>
<td>社区主导，蚂蚁金服技术支持</td>
<td>62.8K</td>
<td>Axure、Sketch</td>
</tr>
</tbody></table>
<ul>
<li><p>据资料统计，在State of CSS的调查中，Ant Design CSS框架位居2020年最佳CSS框架类别排名第九。有4.39%的CSS开发人员已经在使用，并希望继续使用它。</p>
</li>
<li><p>在Github上拥有62.8k颗星、23.8k个fork、以及1.6k个watch。</p>
</li>
</ul>
<hr>
<h2 id="四、选择Ant-Design-Vue框架的理由："><a href="#四、选择Ant-Design-Vue框架的理由：" class="headerlink" title="四、选择Ant Design Vue框架的理由："></a>四、选择Ant Design Vue框架的理由：</h2><ul>
<li>1.组件详细</li>
</ul>
<p>开发人员可以为FormItem添加TextArea、Input、Radio、Checkbox、Date或TimePicker等62中不同模式的组件，其中的参考样式及使用须知详细。</p>
<ul>
<li>2.出色的反馈组件</li>
</ul>
<p>它可以为用户的各项操作提供即时的通知。</p>
<ul>
<li>3.企业级的网站外观</li>
</ul>
<p>Ant Design能够为开发人员提供企业级的网站外观。</p>
<ul>
<li>4.辅助功能</li>
</ul>
<p>它符合ARIA规范，并提供键盘处理和制表等功能。</p>
<ul>
<li>5.节省时间</li>
</ul>
<p>其原型制作方式可以节省大量的开发时间。</p>
<p><img src="" data-original="https://glh508-blog-img.oss-cn-beijing.aliyuncs.com/1598238015509.png" alt=""></p>
<hr>
<h2 id="五、使用用户："><a href="#五、使用用户：" class="headerlink" title="五、使用用户："></a>五、使用用户：</h2><ul>
<li>蚂蚁集团</li>
<li>阿里巴巴</li>
<li>腾讯</li>
<li>百度</li>
<li>口碑</li>
<li>美团</li>
<li>滴滴</li>
<li>饿了么</li>
<li>其他用户</li>
</ul>
<hr>
<h2 id="六、Ant-Design和Ant-Design-Pro"><a href="#六、Ant-Design和Ant-Design-Pro" class="headerlink" title="六、Ant Design和Ant Design Pro"></a>六、Ant Design和Ant Design Pro</h2><p><strong>Ant Design</strong>更多是着重致力于设计规范和基础组件</p>
<p><strong>Ant Design Pro</strong> 直接提炼出典型模板/业务组件/配套设计资源。你不需要重复设计那些复用性高的业务组件，直接引用集合好的业务组件，省事又省力。</p>
<p>可以理解为 Ant Design 是一套 组件库，而 Pro 是使用了这套组件库的完整前端脚手架。</p>
<p><strong>Ant Design Pro</strong> 面向的人群更多企业的中后台开发，企业的后台产品对界面的设计要求并没有那么严格，因为不是面向大众使用的，一般也不过于追求 UI视觉效果，更多的是需要一些基础性功能，它的对于数据的显示和操作交互要求更高。而<strong>Ant Design Pro</strong> 直接把<strong>典型模板/业务组件/配套的设计资源全部给你做齐了</strong>，等于说组件全部都封装好了，你只需要按照<strong>Ant Design Pro</strong> 中给到的配套资源和一套基于 Vue 的中后台管理控制台的脚手架，直接进行搭建就好了，这样可以极大的缩减开发人员的时间成本。</p>
<hr>
<h2 id="七、Ant-Design-Pro-Vue基本介绍"><a href="#七、Ant-Design-Pro-Vue基本介绍" class="headerlink" title="七、Ant Design Pro Vue基本介绍"></a>七、Ant Design Pro Vue基本介绍</h2><h3 id="目录结构"><a href="#目录结构" class="headerlink" title="目录结构"></a>目录结构</h3><pre><code>├── public
│   └── logo.png             # LOGO
|   └── index.html           # Vue 入口模板
├── src
│   ├── api                  # Api ajax 等
│   ├── assets               # 本地静态资源
│   ├── config               # 项目基础配置，包含路由，全局设置
│   ├── components           # 业务通用组件
│   ├── core                 # 项目引导, 全局配置初始化，依赖包引入等
│   ├── router               # Vue-Router
│   ├── store                # Vuex
│   ├── utils                # 工具库
│   ├── locales              # 国际化资源
│   ├── views                # 业务页面入口和常用模板
│   ├── App.vue              # Vue 模板入口
│   └── main.js              # Vue 入口 JS
│   └── permission.js        # 路由守卫(路由权限控制)
├── tests                    # 测试工具
├── README.md
└── package.json</code></pre><h3 id="路由和菜单"><a href="#路由和菜单" class="headerlink" title="路由和菜单"></a>路由和菜单</h3><h5 id="基本结构"><a href="#基本结构" class="headerlink" title="基本结构"></a>基本结构</h5><p>路由和菜单是组织起一个应用的关键骨架，pro 中的路由为了方便管理，使用了中心化的方式，在 router.config.js 统一配置和管理。</p>
<ul>
<li>路由管理 通过约定的语法根据在router.config.js中配置路由。</li>
<li>菜单生成 根据路由配置来生成菜单。菜单项名称，嵌套路径与路由高度耦合。</li>
<li>面包屑 组件 PageHeader 中内置的面包屑也可由脚手架提供的配置信息自动生成。</li>
</ul>
<h5 id="路由"><a href="#路由" class="headerlink" title="路由"></a>路由</h5><p>目前脚手架中所有的路由都通过 router.config.js 来统一管理，在 vue-router 的配置中我们增加了一些参数，如 hideChildrenInMenu,meta.title,meta.icon,meta.permission，来辅助生成菜单。其中：</p>
<ul>
<li>hideChildrenInMenu 用于隐藏不需要在菜单中展示的子路由。用法可以查看 分步表单 的配置。</li>
<li>hidden 可以在菜单中不展示这个路由，包括子路由。效果可以查看 other 下的路由配置。</li>
<li>meta.title 和 meta.icon分别代表生成菜单项的文本和图标。</li>
<li>meta.permission 用来配置这个路由的权限，如果配置了将会验证当前用户的权限，并决定是否展示 *（默认情况下）。</li>
<li>meta.hidden 可以强制子菜单不显示在菜单上(和父级 hideChildrenInMenu 配合)</li>
<li>meta.hiddenHeaderContent 可以强制当前页面不显示 PageHeader 组件中的页面带的 面包屑和页面标题栏</li>
</ul>
<h6 id="路由配置项"><a href="#路由配置项" class="headerlink" title="路由配置项"></a>路由配置项</h6><pre><code>/**
 * 路由配置说明：
 * 建议：sider menu 请不要超过三级菜单，若超过三级菜单，则应该设计为顶部主菜单 配合左侧次级菜单
 *
 **/
 {
  redirect: noredirect,  //重定向
  name: &#39;router-name&#39;,   //路由名称
  hidden: true,          //可以在菜单中不展示这个路由，包括子路由。效果可以查看 other 下的路由配置。
  meta: {
    title: &#39;title&#39;,      //菜单项名称
    icon: &#39;a-icon&#39;,      //菜单项图标
    keepAlive: true,     //缓存页面
    permission：[string]   //用来配置这个路由的权限，如果配置了将会验证当前用户的权限，并决定是否展示 *（默认情况下）
    hiddenHeaderContent: true,   //可以强制当前页面不显示 PageHeader 组件中的页面带的 面包屑和页面标题栏
  }
}</code></pre><p>具体请参考 <a href="https://note.youdao.com/" target="_blank" rel="noopener">https://pro.loacg.com/docs/router-and-nav</a></p>
<h5 id="菜单"><a href="#菜单" class="headerlink" title="菜单"></a>菜单</h5><p>菜单根据 router.config.js 生成，具体逻辑在 src/store/modules/permission.js 中的 actions.GenerateRoutes 方法实现。</p>
<h3 id="Ant-Design-Pro-的布局"><a href="#Ant-Design-Pro-的布局" class="headerlink" title="Ant Design Pro 的布局"></a>Ant Design Pro 的布局</h3><p>在 Ant Design Pro 中，我们抽离了使用过程中的通用布局，都放在 /components/layouts 目录中，分别为：</p>
<ul>
<li>BasicLayout：基础页面布局，包含了头部导航，侧边栏和通知栏：</li>
<li>UserLayout：抽离出用于登陆注册页面的通用布局</li>
<li>PageView：基础布局，包含了面包屑，和中间内容区 (slot)</li>
<li>RouterView：空布局，专门为了二级菜单内容区自定义</li>
<li>BlankLayout：空白的布局</li>
</ul>
<h3 id="定义全局样式"><a href="#定义全局样式" class="headerlink" title="定义全局样式"></a>定义全局样式</h3><pre><code>/* 定义全局样式 */
:global(.text) {
  font-size: 16px;
}

/* 定义多个全局样式 */
:global {
  .footer {
    color: #ccc;
  }
  .sider {
    background: #ebebeb;
  }
}
//覆盖组件样式
// 使用 css 时可以用 &gt;&gt;&gt; 进行样式穿透
.test-wrapper &gt;&gt;&gt; .ant-select {
    font-size: 16px;
}

// 使用 scss, less 时，可以用 /deep/ 进行样式穿透
.test-wrapper /deep/ .ant-select {
    font-size: 16px;
}

// less CSS modules 时亦可用 :global 进行覆盖
.test-wrapper {
    :global {
        .ant-select {
            font-size: 16px;
        }
    }
}</code></pre><h3 id="与服务器交互"><a href="#与服务器交互" class="headerlink" title="与服务器交互"></a>与服务器交互</h3><p>在 Ant Design Pro 中，一个完整的前端 UI 交互到服务端处理流程是这样的：</p>
<ol>
<li>UI 组件交互操作；</li>
<li>调用统一管理的 api service 请求函数；</li>
<li>使用封装的 request.js 发送请求；</li>
<li>获取服务端返回；</li>
<li>更新 data。</li>
</ol>
<p>从上面的流程可以看出，为了方便管理维护，统一的请求处理都放在 @/src/api 文件夹中，并且一般按照 model 纬度进行拆分文件，如：</p>
<pre><code>api/
  user.js
  permission.js
  goods.js
  ...</code></pre><p>其中，@/src/utils/request.js 是基于 axios 的封装，便于统一处理 POST，GET 等请求参数，请求头，以及错误提示信息等。具体可以参看 request.js。 它封装了全局 request 拦截器、response 拦截器、统一的错误处理、baseURL 设置等。</p>
<p>例如在 api 中的一个请求用户信息的例子：</p>
<pre><code>// api/user.js
import { axios } fromm &#39;@/utils/request&#39;

const api = {
    info: &#39;/user&#39;,
    list: &#39;/users&#39;
}

// 根据用户 id 获取用户信息
export function getUser (id) {
    return axios({
        url: `${api.user}/${id}`,
        method: &#39;get&#39;
    })
}

// 增加用户
export function addUser (parameter) {
    return axios({
        url: api.user,
        method: &#39;post&#39;,
        data: parameter
    })
}

// 更新用户 // or (id, parameter)
export function updateUser (parameter) {
    return axios({
        url: `${api.user}/${parameter.id}`, // or `${api.user}/${id}`
        method: &#39;put&#39;,
        data: parameter
    })
}

// 删除用户
export function deleteUser (id) {
    return axios({
        url: `${api.user}/${id}`,
        method: &#39;delete&#39;,
        data: parameter
    })
}

// 获取用户列表 parameter: { pageSize: 10, pageNo: 1 }
export function getUsers (parameter) {
    return axios({
        url: api.list,
        method: &#39;get&#39;,
        params: parameter
    })
}
&lt;template&gt;
    &lt;div&gt;
        &lt;a-button @click=&quot;queryUser&quot;&gt;&lt;/a-button&gt;

        &lt;a-table :dataSource=&quot;list&quot;&gt;
        &lt;/a-table&gt;
    &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import { getUser, getUsers } from &#39;@/api/user&#39;

export default {
    data () {
        return {
            id: 0,
            queryParam: {
                pageSize: 10,
                pageNo: 1,
                username: &#39;&#39;
            },
            info: {},
            list: []
        }
    },
    methods: {
        queryUser () {
            const { $message } = this
            getUser(this.id).then(res =&gt; {
                this.info = res.data
            }).catch(err =&gt; {
                $message.error(`load user err: ${err.message}`)
            })
        },
        queryUsers () {
            getUsers(this.queryParam).then(res =&gt; {
                this.list = res
            })
        }
    }
}
&lt;/script&gt;
**
     * 获取裁剪后的图片
     */
    cropImage () {
      this.form.cropimg = this.$refs.cropper.getCroppedCanvas().toDataURL();
    },
    /**
     * 确认裁剪
     */
    sureCrop () {
      this.dialogVisible = false
    },
    /**
     * 上传裁剪后的图片到服务器
     */
    upCropImg () {
      //判断是否是新增还是编辑
      if (this.$route.query.id &amp;&amp; this.$route.query.id != &#39;&#39;) {
        //如果是编辑的就直接提交
        this.onSubmit()
      } else {
        //否则先上传裁剪图片，将64位图片转换为二进制数据流
        var formdata1 = new FormData();// 创建form对象
        formdata1.append(&#39;file&#39;, convertBase64UrlToBlob(this.form.cropimg), &#39;aaa.png&#39;);//
        this.$ajax
          .post(this.$api + &quot;/upload/singleUploadImg&quot;, formdata1, { headers: { &#39;Content-Type&#39;: &#39;multipart/form-data&#39; } })
          .then(response =&gt; {
            if (response.data.msg == &quot;success&quot; &amp;&amp; response.data.code == 1) {
              this.form.imgUrl = response.data.data.imgUrl
              this.onSubmit()
            } else {
              console.log(response)
              this.$message.error(response.data.msg);
            }
          })
          .catch(function (error) {
            console.log(error);
          });
      }

    },</code></pre><h3 id="引入外部模块"><a href="#引入外部模块" class="headerlink" title="引入外部模块"></a>引入外部模块</h3><pre><code>$ npm install &#39;组件名字&#39; --save</code></pre><h5 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h5><pre><code>//全局引入
import Vue from &#39;vue&#39;
import VueQuillEditor from &#39;vue-quill-editor&#39;

// require styles
import &#39;quill/dist/quill.core.css&#39;
import &#39;quill/dist/quill.snow.css&#39;
import &#39;quill/dist/quill.bubble.css&#39;

Vue.use(VueQuillEditor, /* { default global options } */)
12345678910
&lt;template&gt;
    &lt;div&gt;
        &lt;quill-editor ref=&quot;myTextEditor&quot;
                      v-model=&quot;content&quot;
                      :config=&quot;editorOption&quot;
                      @blur=&quot;onEditorBlur($event)&quot;
                      @focus=&quot;onEditorFocus($event)&quot;
                      @ready=&quot;onEditorReady($event)&quot;&gt;
        &lt;/quill-editor&gt;
    &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
//按需加载
import &#39;quill/dist/quill.core.css&#39;
import &#39;quill/dist/quill.snow.css&#39;
import &#39;quill/dist/quill.bubble.css&#39;
import { quillEditor } from &#39;vue-quill-editor&#39;

export default {
  components: {
    quillEditor
  },
  data () {
      return {
          content: &#39;&lt;h2&gt;I am Example&lt;/h2&gt;&#39;,
          editorOption: {
           // something config
          }
      }
  },
  // 如果需要手动控制数据同步，父组件需要显式地处理changed事件
  methods: {
    onEditorBlur(editor) {
      console.log(&#39;editor blur!&#39;, editor)
    },
    onEditorFocus(editor) {
      console.log(&#39;editor focus!&#39;, editor)
    },
    onEditorReady(editor) {
      console.log(&#39;editor ready!&#39;, editor)
    },
    onEditorChange({ editor, html, text }) {
      // console.log(&#39;editor change!&#39;, editor, html, text)
      this.content = html
    }
  },
  // 如果你需要得到当前的editor对象来做一些事情，你可以像下面这样定义一个方法属性来获取当前的editor对象，实际上这里的$refs对应的是当前组件内所有关联了ref属性的组件元素对象
  computed: {
    editor() {
      return this.$refs.myTextEditor.quillEditor
    }
  },
  mounted() {
    // you can use current editor object to do something(editor methods)
    console.log(&#39;this is my editor&#39;, this.editor)
    // this.editor to do something...
  }
}
&lt;/script&gt;</code></pre><h3 id="引入业务图标"><a href="#引入业务图标" class="headerlink" title="引入业务图标"></a>引入业务图标</h3><p>参考：<a href="https://pro.loacg.com/docs/biz-icon、" target="_blank" rel="noopener">https://pro.loacg.com/docs/biz-icon、</a></p>
<h3 id="国际化"><a href="#国际化" class="headerlink" title="国际化"></a>国际化</h3><p>参考：<a href="https://pro.loacg.com/docs/i18n" target="_blank" rel="noopener">https://pro.loacg.com/docs/i18n</a></p>
<h3 id="权限管理"><a href="#权限管理" class="headerlink" title="权限管理"></a>权限管理</h3><p>参考：<a href="https://pro.loacg.com/docs/authority-management" target="_blank" rel="noopener">https://pro.loacg.com/docs/authority-management</a></p>
<h3 id="自定义使用规则"><a href="#自定义使用规则" class="headerlink" title="自定义使用规则"></a>自定义使用规则</h3><ul>
<li>修改网站icon的文件地址在 public文件夹中把logo.png换成自定义的，也可在public/index.html自定义</li>
</ul>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;zh-cmn-Hans&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width,initial-scale=1.0&quot;&gt;
    &lt;link rel=&quot;icon&quot; href=&quot;&lt;%= BASE_URL %&gt;logo.png&quot;&gt;
    &lt;title&gt;共享云店&lt;/title&gt;
    &lt;style&gt;#loading-mask{position:fixed;left:0;top:0;height:100%;width:100%;background:#fff;user-select:none;z-index:9999;overflow:hidden}.loading-wrapper{position:absolute;top:50%;left:50%;transform:translate(-50%,-100%)}.loading-dot{animation:antRotate 1.2s infinite linear;transform:rotate(45deg);position:relative;display:inline-block;font-size:64px;width:64px;height:64px;box-sizing:border-box}.loading-dot i{width:22px;height:22px;position:absolute;display:block;background-color:#1890ff;border-radius:100%;transform:scale(.75);transform-origin:50% 50%;opacity:.3;animation:antSpinMove 1s infinite linear alternate}.loading-dot i:nth-child(1){top:0;left:0}.loading-dot i:nth-child(2){top:0;right:0;-webkit-animation-delay:.4s;animation-delay:.4s}.loading-dot i:nth-child(3){right:0;bottom:0;-webkit-animation-delay:.8s;animation-delay:.8s}.loading-dot i:nth-child(4){bottom:0;left:0;-webkit-animation-delay:1.2s;animation-delay:1.2s}@keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@-webkit-keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@keyframes antSpinMove{to{opacity:1}}@-webkit-keyframes antSpinMove{to{opacity:1}}&lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;noscript&gt;
      &lt;strong&gt;We&#39;re sorry but vue-antd-pro doesn&#39;t work properly without JavaScript enabled. Please enable it to continue.&lt;/strong&gt;
    &lt;/noscript&gt;
    &lt;div id=&quot;app&quot;&gt;
      &lt;div id=&quot;loading-mask&quot;&gt;
          &lt;div class=&quot;loading-wrapper&quot;&gt;
            &lt;span class=&quot;loading-dot loading-dot-spin&quot;&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;
          &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- built files will be auto injected --&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre><p>-更换logo在src\components\tools\Logo.vue中更换</p>
<pre><code>&lt;template&gt;
  &lt;div class=&quot;logo&quot;&gt;
    &lt;router-link :to=&quot;{name:&#39;dashboard&#39;}&quot;&gt;
      &lt;LogoSvg alt=&quot;logo&quot; /&gt;   //这是logo
      &lt;h1 v-if=&quot;showTitle&quot;&gt;{{ title }}&lt;/h1&gt;   //这是网站标题
    &lt;/router-link&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import LogoSvg from &#39;@/assets/logo.svg?inline&#39;;
export default {
  name: &#39;Logo&#39;,
  components: {
    LogoSvg
  },
  props: {
    title: {
      type: String,
      default: &#39;Admin For Ok&#39;,    //网站默认标题
      required: false
    },
    showTitle: {                  //是否显示网站标题，默认不显示
      type: Boolean,
      default: true,
      required: false
    }
  }
}
&lt;/script&gt;</code></pre><h3 id="pro权限管理和路由控制思路分析-粗略分析"><a href="#pro权限管理和路由控制思路分析-粗略分析" class="headerlink" title="pro权限管理和路由控制思路分析(粗略分析)"></a>pro权限管理和路由控制思路分析(粗略分析)</h3><ul>
<li>主要是通过三个文件实现,src\mock\services\user.js文件通过登陆的角色获取对应的鉴权规则，具体可查看该文件下的源码</li>
<li>src\config\router.config.js文件为路由配置文件，可增加路由取消路由等，变量asyncRouterMap为主要路由数组集合，可配置鉴权权限，变量constantRouterMap为基础路由，不参与鉴权</li>
<li>src\permission.js文件为动态配置路由的主要逻辑，代码如下</li>
</ul>
<pre><code>import Vue from &#39;vue&#39;
import router from &#39;./router&#39;
import store from &#39;./store&#39;

import NProgress from &#39;nprogress&#39; // progress bar
import &#39;nprogress/nprogress.css&#39; // progress bar style
import notification from &#39;ant-design-vue/es/notification&#39;
import { setDocumentTitle, domTitle } from &#39;@/utils/domUtil&#39;
import { ACCESS_TOKEN } from &#39;@/store/mutation-types&#39;

NProgress.configure({ showSpinner: false }) // NProgress Configuration

const whiteList = [&#39;login&#39;, &#39;register&#39;, &#39;registerResult&#39;] // no redirect whitelist配置白名单

router.beforeEach((to, from, next) =&gt; {
  NProgress.start() // start progress bar
  //生成动态网站标题
  to.meta &amp;&amp; (typeof to.meta.title !== &#39;undefined&#39; &amp;&amp; setDocumentTitle(`${to.meta.title} - ${domTitle}`))
  if (Vue.ls.get(ACCESS_TOKEN)) {
    /* has token 如果有token并且是从登录页来的就直接跳到工作空间*/
    if (to.path === &#39;/user/login&#39;) {
      next({ path: &#39;/dashboard/workplace&#39; })
      NProgress.done()
    } else {
    //否则检测是不是没有检测到规则，请求获取用户信息，获取用户权限
      if (store.getters.roles.length === 0) {
      //请求mock模拟数据获取用户权限
        store
          .dispatch(&#39;GetInfo&#39;)
          .then(res =&gt; {
            const roles = res.result &amp;&amp; res.result.role
            //调用src\store\modules\permission.js里面的GenerateRoutes方法，处理数据
            store.dispatch(&#39;GenerateRoutes&#39;, { roles }).then(() =&gt; {
              // 根据roles权限生成可访问的路由表
              // 动态添加可访问路由表
              router.addRoutes(store.getters.addRouters)
              const redirect = decodeURIComponent(from.query.redirect || to.path)
              if (to.path === redirect) {
                // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
                next({ ...to, replace: true })
              } else {
                // 跳转到目的路由
                next({ path: redirect })
              }
            })
          })
          .catch(() =&gt; {
            notification.error({
              message: &#39;错误&#39;,
              description: &#39;请求用户信息失败，请重试&#39;
            })
            store.dispatch(&#39;Logout&#39;).then(() =&gt; {
              next({ path: &#39;/user/login&#39;, query: { redirect: to.fullPath } })
            })
          })
      } else {
        next()
      }
    }
  } else {
    if (whiteList.includes(to.name)) {
      // 在免登录白名单，直接进入
      next()
    } else {
      next({ path: &#39;/user/login&#39;, query: { redirect: to.fullPath } })
      NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
    }
  }
})

router.afterEach(() =&gt; {
  NProgress.done() // finish progress bar
})</code></pre><ul>
<li>src\store\modules\permission.js文件为路由数据的详细处理逻辑，配合src\permission.js文件使用，代码如下：</li>
</ul>
<pre><code>import { asyncRouterMap, constantRouterMap } from &#39;@/config/router.config&#39;

/**
 * 过滤账户是否拥有某一个权限，并将菜单从加载列表移除
 *
 * @param permission
 * @param route
 * @returns {boolean}
 */
function hasPermission (permission, route) {
  if (route.meta &amp;&amp; route.meta.permission) {
    let flag = false
    for (let i = 0, len = permission.length; i &lt; len; i++) {
      flag = route.meta.permission.includes(permission[i])
      if (flag) {
        return true
      }
    }
    return false
  }
  return true
}

/**
 * 单账户多角色时，使用该方法可过滤角色不存在的菜单
 *
 * @param roles
 * @param route
 * @returns {*}
 */
// eslint-disable-next-line
function hasRole(roles, route) {
  if (route.meta &amp;&amp; route.meta.roles) {
    return route.meta.roles.includes(roles.id)
  } else {
    return true
  }
}

function filterAsyncRouter (routerMap, roles) {
  const accessedRouters = routerMap.filter(route =&gt; {
    if (hasPermission(roles.permissionList, route)) {
      if (route.children &amp;&amp; route.children.length) {
        route.children = filterAsyncRouter(route.children, roles)
      }
      return true
    }
    return false
  })
  return accessedRouters
}

const permission = {
  state: {
    routers: constantRouterMap,
    addRouters: []
  },
  mutations: {
    SET_ROUTERS: (state, routers) =&gt; {
      state.addRouters = routers
      state.routers = constantRouterMap.concat(routers)
    }
  },
  actions: {
    GenerateRoutes ({ commit }, data) {
      return new Promise(resolve =&gt; {
        const { roles } = data
        const accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
        commit(&#39;SET_ROUTERS&#39;, accessedRouters)
        resolve()
      })
    }
  }
}

export default permission</code></pre><h3 id="跨域请求设置"><a href="#跨域请求设置" class="headerlink" title="跨域请求设置"></a>跨域请求设置</h3><p>在vue.config.js文件中修改</p>
<pre><code> // 配置跨域
  devServer: {
    // development server port 8000
    // port: 8000,
    proxy: {
      &#39;/apis&#39;: {
        // target: &#39;https://mock.ihx.me/mock/5baf3052f7da7e07e04a5116/antd-pro&#39;,
        target: &#39;http://192.168.1.73:8092/okcloud/&#39;,
        // target: &#39;http://39.107.78.120:8083/okcloud/&#39;,

        ws: false,
        changeOrigin: true,  //是否允许跨域
        pathRewrite: {
          &#39;^/apis&#39;: &#39;&#39;
        }
      }
    }</code></pre><h3 id="axios拦截器"><a href="#axios拦截器" class="headerlink" title="axios拦截器"></a>axios拦截器</h3><p>在文件src\utils\request.js中设置</p>
<pre><code>// request interceptor
service.interceptors.request.use(config =&gt; {
  const token = Vue.ls.get(ACCESS_TOKEN)
  if (token) {
    config.headers[&#39;okcloud_token&#39;] = token // 让每个请求携带自定义 token 请根据实际情况自行修改
  }
  return config
}, err)

// response interceptor
service.interceptors.response.use((response) =&gt; {
  if (response.data.code === 10000) {
    notification.warning({
      message: &#39;提示&#39;,
      description: response.data.message
    })
  } else {
    return response.data
  }
}, err)</code></pre><h3 id="自定义角色的菜单权限"><a href="#自定义角色的菜单权限" class="headerlink" title="自定义角色的菜单权限"></a>自定义角色的菜单权限</h3><ul>
<li>在src\main.js文件中注释掉”// import ‘./permission’ // permission control 权限控制”</li>
<li>自定义路由权限文件src\routeGuard.js，代码如下</li>
</ul>
<pre><code>import Vue from &#39;vue&#39;
import router from &#39;./router&#39;
// import store from &#39;./store&#39;

import NProgress from &#39;nprogress&#39; // progress bar
import &#39;nprogress/nprogress.css&#39; // progress bar style
import { setDocumentTitle, domTitle } from &#39;@/utils/domUtil&#39;
import { ACCESS_TOKEN } from &#39;@/store/mutation-types&#39;

NProgress.configure({ showSpinner: false }) // NProgress Configuration

router.beforeEach((to, from, next) =&gt; {
  NProgress.start() // start progress bar
  to.meta &amp;&amp; (typeof to.meta.title !== &#39;undefined&#39; &amp;&amp; setDocumentTitle(`${to.meta.title} - ${domTitle}`))
  if (to.path === &#39;/user/login&#39; &amp;&amp; Vue.ls.get(ACCESS_TOKEN)) {
    next({ path: &#39;/dashboard/workplace&#39; })
    NProgress.done()
  } else if (to.path !== &#39;/user/login&#39; &amp;&amp; !Vue.ls.get(ACCESS_TOKEN)) {
    next({ path: &#39;/user/login&#39; })
    NProgress.done()
  } else {
    next()
    NProgress.done()
  }
})

router.afterEach(() =&gt; {
  NProgress.done() // finish progress bar
})</code></pre><ul>
<li>在main.js中引入import ‘./routeGuard’</li>
<li>对src\components\Menu\menu.js文件进行自定义菜单改造</li>
<li>在src\store\modules\app.js文件中store加入menu,在actions中进行获取菜单的异步操作，获取菜单信息，然后进行全局变量动态获取</li>
<li>在src\layouts\BasicLayout.vue中进行全局变量的引用</li>
</ul>
<pre><code>    ...mapState({
      // 动态主路由
      menus: state =&gt; state.app.menu
    }),</code></pre><p>动态方法的引用</p>
<pre><code>...mapActions([&#39;setSidebar&#39;, &#39;setMenu&#39;]),</code></pre><p>调用获取动态方法</p>
<pre><code>this.setMenu()</code></pre>
            </div>
            <hr/>

            

    <div class="reprint" id="reprint-statement">
        
            <div class="reprint__author">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-user">
                        文章作者:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="/blog/about" rel="external nofollow noreferrer">glh</a>
                </span>
            </div>
            <div class="reprint__type">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-link">
                        文章链接:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="https://blog.glh508.top/blog/post/cf3f0e22.html">https://blog.glh508.top/blog/post/cf3f0e22.html</a>
                </span>
            </div>
            <div class="reprint__notice">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-copyright">
                        版权声明:
                    </i>
                </span>
                <span class="reprint-info">
                    本博客所有文章除特別声明外，均采用
                    <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>
                    许可协议。转载请注明来源
                    <a href="/blog/about" target="_blank">glh</a>
                    !
                </span>
            </div>
        
    </div>

    <script async defer>
      document.addEventListener("copy", function (e) {
        let toastHTML = '<span>复制成功，请遵循本文的转载规则</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">查看</a>';
        M.toast({html: toastHTML})
      });

      function navToReprintStatement() {
        $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800);
      }
    </script>



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            
                                <a href="/blog/tags/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6/">
                                    <span class="chip bg-color">前端框架</span>
                                </a>
                            
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="/blog/libs/share/css/share.min.css">
<div id="article-share">

    

    

</div>

                </div>
            </div>
            
                <style>
    #reward {
        margin: 40px 0;
        text-align: center;
    }

    #reward .reward-link {
        font-size: 1.4rem;
        line-height: 38px;
    }

    #reward .btn-floating:hover {
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2), 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    #rewardModal {
        width: 320px;
        height: 350px;
    }

    #rewardModal .reward-title {
        margin: 15px auto;
        padding-bottom: 5px;
    }

    #rewardModal .modal-content {
        padding: 10px;
    }

    #rewardModal .close {
        position: absolute;
        right: 15px;
        top: 15px;
        color: rgba(0, 0, 0, 0.5);
        font-size: 1.3rem;
        line-height: 20px;
        cursor: pointer;
    }

    #rewardModal .close:hover {
        color: #ef5350;
        transform: scale(1.3);
        -moz-transform:scale(1.3);
        -webkit-transform:scale(1.3);
        -o-transform:scale(1.3);
    }

    #rewardModal .reward-tabs {
        margin: 0 auto;
        width: 210px;
    }

    .reward-tabs .tabs {
        height: 38px;
        margin: 10px auto;
        padding-left: 0;
    }

    .reward-content ul {
        padding-left: 0 !important;
    }

    .reward-tabs .tabs .tab {
        height: 38px;
        line-height: 38px;
    }

    .reward-tabs .tab a {
        color: #fff;
        background-color: #ccc;
    }

    .reward-tabs .tab a:hover {
        background-color: #ccc;
        color: #fff;
    }

    .reward-tabs .wechat-tab .active {
        color: #fff !important;
        background-color: #22AB38 !important;
    }

    .reward-tabs .alipay-tab .active {
        color: #fff !important;
        background-color: #019FE8 !important;
    }

    .reward-tabs .reward-img {
        width: 210px;
        height: 210px;
    }
</style>

<div id="reward">
    <a href="#rewardModal" class="reward-link modal-trigger btn-floating btn-medium waves-effect waves-light red">赏</a>

    <!-- Modal Structure -->
    <div id="rewardModal" class="modal">
        <div class="modal-content">
            <a class="close modal-close"><i class="fas fa-times"></i></a>
            <h4 class="reward-title">你的赏识是我前进的动力</h4>
            <div class="reward-content">
                <div class="reward-tabs">
                    <ul class="tabs row">
                        <li class="tab col s6 alipay-tab waves-effect waves-light"><a href="#alipay">支付宝</a></li>
                        <li class="tab col s6 wechat-tab waves-effect waves-light"><a href="#wechat">微 信</a></li>
                    </ul>
                    <div id="alipay">
                        <img src="" data-original="/blog/medias/reward/alipay.jpg" class="reward-img" alt="支付宝打赏二维码">
                    </div>
                    <div id="wechat">
                        <img src="" data-original="/blog/medias/reward/wechat.png" class="reward-img" alt="微信打赏二维码">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    $(function () {
        $('.tabs').tabs();
    });
</script>

            
        </div>
    </div>

    

    

    

    

    
        <style>
    .valine-card {
        margin: 1.5rem auto;
    }

    .valine-card .card-content {
        padding: 20px 20px 5px 20px;
    }

    #vcomments textarea {
        box-sizing: border-box;
        background: url("/blog/medias/comment_bg.png") 100% 100% no-repeat;
    }

    #vcomments p {
        margin: 2px 2px 10px;
        font-size: 1.05rem;
        line-height: 1.78rem;
    }

    #vcomments blockquote p {
        text-indent: 0.2rem;
    }

    #vcomments a {
        padding: 0 2px;
        color: #4cbf30;
        font-weight: 500;
        text-decoration: none;
    }

    #vcomments img {
        max-width: 100%;
        height: auto;
        cursor: pointer;
    }

    #vcomments ol li {
        list-style-type: decimal;
    }

    #vcomments ol,
    ul {
        display: block;
        padding-left: 2em;
        word-spacing: 0.05rem;
    }

    #vcomments ul li,
    ol li {
        display: list-item;
        line-height: 1.8rem;
        font-size: 1rem;
    }

    #vcomments ul li {
        list-style-type: disc;
    }

    #vcomments ul ul li {
        list-style-type: circle;
    }

    #vcomments table, th, td {
        padding: 12px 13px;
        border: 1px solid #dfe2e5;
    }

    #vcomments table, th, td {
        border: 0;
    }

    table tr:nth-child(2n), thead {
        background-color: #fafafa;
    }

    #vcomments table th {
        background-color: #f2f2f2;
        min-width: 80px;
    }

    #vcomments table td {
        min-width: 80px;
    }

    #vcomments h1 {
        font-size: 1.85rem;
        font-weight: bold;
        line-height: 2.2rem;
    }

    #vcomments h2 {
        font-size: 1.65rem;
        font-weight: bold;
        line-height: 1.9rem;
    }

    #vcomments h3 {
        font-size: 1.45rem;
        font-weight: bold;
        line-height: 1.7rem;
    }

    #vcomments h4 {
        font-size: 1.25rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    #vcomments h5 {
        font-size: 1.1rem;
        font-weight: bold;
        line-height: 1.4rem;
    }

    #vcomments h6 {
        font-size: 1rem;
        line-height: 1.3rem;
    }

    #vcomments p {
        font-size: 1rem;
        line-height: 1.5rem;
    }

    #vcomments hr {
        margin: 12px 0;
        border: 0;
        border-top: 1px solid #ccc;
    }

    #vcomments blockquote {
        margin: 15px 0;
        border-left: 5px solid #42b983;
        padding: 1rem 0.8rem 0.3rem 0.8rem;
        color: #666;
        background-color: rgba(66, 185, 131, .1);
    }

    #vcomments pre {
        font-family: monospace, monospace;
        padding: 1.2em;
        margin: .5em 0;
        background: #272822;
        overflow: auto;
        border-radius: 0.3em;
        tab-size: 4;
    }

    #vcomments code {
        font-family: monospace, monospace;
        padding: 1px 3px;
        font-size: 0.92rem;
        color: #e96900;
        background-color: #f8f8f8;
        border-radius: 2px;
    }

    #vcomments pre code {
        font-family: monospace, monospace;
        padding: 0;
        color: #e8eaf6;
        background-color: #272822;
    }

    #vcomments pre[class*="language-"] {
        padding: 1.2em;
        margin: .5em 0;
    }

    #vcomments code[class*="language-"],
    pre[class*="language-"] {
        color: #e8eaf6;
    }

    #vcomments [type="checkbox"]:not(:checked), [type="checkbox"]:checked {
        position: inherit;
        margin-left: -1.3rem;
        margin-right: 0.4rem;
        margin-top: -1px;
        vertical-align: middle;
        left: unset;
        visibility: visible;
    }

    #vcomments b,
    strong {
        font-weight: bold;
    }

    #vcomments dfn {
        font-style: italic;
    }

    #vcomments small {
        font-size: 85%;
    }

    #vcomments cite {
        font-style: normal;
    }

    #vcomments mark {
        background-color: #fcf8e3;
        padding: .2em;
    }

    #vcomments table, th, td {
        padding: 12px 13px;
        border: 1px solid #dfe2e5;
    }

    table tr:nth-child(2n), thead {
        background-color: #fafafa;
    }

    #vcomments table th {
        background-color: #f2f2f2;
        min-width: 80px;
    }

    #vcomments table td {
        min-width: 80px;
    }

    #vcomments [type="checkbox"]:not(:checked), [type="checkbox"]:checked {
        position: inherit;
        margin-left: -1.3rem;
        margin-right: 0.4rem;
        margin-top: -1px;
        vertical-align: middle;
        left: unset;
        visibility: visible;
    }
</style>

<div class="card valine-card" data-aos="fade-up">
    <div class="comment_headling" style="font-size: 20px; font-weight: 700; position: relative; padding-left: 20px; top: 15px; padding-bottom: 5px;">
        <i class="fas fa-comments fa-fw" aria-hidden="true"></i>
        <span>评论</span>
    </div>
    <div id="vcomments" class="card-content" style="display: grid">
    </div>
</div>

<script src="/blog/libs/valine/av-min.js"></script>
<script src="https://sky508.gitee.io/blog/libs/valine/Valine.min.js"></script>
<script>
    new Valine({
        el: '#vcomments',
        appId: 't5C6WwDat4msTdtyG9E8lSU7-gzGzoHsz',
        appKey: 'xE7bK8SjGw38UDPb7vLi5qsb',
        notify: 'true' === 'true',
        verify: 'true' === 'true',
        visitor: 'true' === 'true',
        avatar: 'mm',
        pageSize: '10',
        lang: 'zh-cn',
        placeholder: '欢迎留下您的讨论'
    });
</script>

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="far fa-dot-circle"></i>&nbsp;本篇
            </div>
            <div class="card">
                <a href="/blog/post/cf3f0e22.html">
                    <div class="card-image">
                        
                        
                        <img src="" data-original="https://glh508-blog-img.oss-cn-beijing.aliyuncs.com/img/17.jpg" class="responsive-img" alt="ant-design简介">
                        
                        <span class="card-title">ant-design简介</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            一、简介由阿里巴巴开发的Ant Design是一种Javascript库类型的ReactJS组件库。通过将屏幕区域分为24列网格，它增加了用户对于可见区域的自定义能力。同时，它通过各种填充（filled）和轮廓（outlined）图标，来满
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2020-08-24
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/blog/categories/%E6%8A%80%E5%B7%A7%E4%BB%8B%E7%BB%8D/" class="post-category">
                                    技巧介绍
                                </a>
                            
                            
                        </span>
                    </div>
                </div>

                
                <div class="card-action article-tags">
                    
                    <a href="/blog/tags/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6/">
                        <span class="chip bg-color">前端框架</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                下一篇&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/blog/post/bb86fde6.html">
                    <div class="card-image">
                        
                        
                        <img src="" data-original="https://glh508-blog-img.oss-cn-beijing.aliyuncs.com/img/17.jpg" class="responsive-img" alt="Typora设置本地图片存储位置及图片服务器上传位置">
                        
                        <span class="card-title">Typora设置本地图片存储位置及图片服务器上传位置</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            一、设置原因
情况一：在typora默认的配置下，复制或者剪切后的图片都是会默认保存在C盘的某个位置，这样非常不合理，而且就算你先保存在其他固定位置，你还得重新输入图片的位置，显得麻烦
情况二：你把md文件发给别人，然后里面包含图片，但是图
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2020-07-25
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/blog/categories/typora/" class="post-category">
                                    typora
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/blog/tags/typora/">
                        <span class="chip bg-color">typora</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>



<!-- 代码块功能依赖 -->
<script type="text/javascript" src="/blog/libs/codeBlock/codeBlockFuction.js"></script>

<!-- 代码语言 -->

<script type="text/javascript" src="/blog/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="/blog/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="/blog/libs/codeBlock/codeShrink.js"></script>


<!-- 代码块折行 -->

<style type="text/css">
code[class*="language-"], pre[class*="language-"] { white-space: pre !important; }
</style>


    </div>
    <div id="toc-aside" class="expanded col l3 hide-on-med-and-down">
        <div class="toc-widget">
            <div class="toc-title"><i class="far fa-list-alt"></i>&nbsp;&nbsp;目录</div>
            <div id="toc-content"></div>
        </div>
    </div>
</div>

<!-- TOC 悬浮按钮. -->

<div id="floating-toc-btn" class="hide-on-med-and-down">
    <a class="btn-floating btn-large bg-color">
        <i class="fas fa-list-ul"></i>
    </a>
</div>


<script src="https://sky508.gitee.io/blog/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('0'),
            headingSelector: 'h2, h3, h4'
        });

        // modify the toc link href to support Chinese.
        let i = 0;
        let tocHeading = 'toc-heading-';
        $('#toc-content a').each(function () {
            $(this).attr('href', '#' + tocHeading + (++i));
        });

        // modify the heading title id to support Chinese.
        i = 0;
        $('#articleContent').children('h2, h3, h4').each(function () {
            $(this).attr('id', tocHeading + (++i));
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });

        
        /* 修复文章卡片 div 的宽度. */
        let fixPostCardWidth = function (srcId, targetId) {
            let srcDiv = $('#' + srcId);
            if (srcDiv.length === 0) {
                return;
            }

            let w = srcDiv.width();
            if (w >= 450) {
                w = w + 21;
            } else if (w >= 350 && w < 450) {
                w = w + 18;
            } else if (w >= 300 && w < 350) {
                w = w + 16;
            } else {
                w = w + 14;
            }
            $('#' + targetId).width(w);
        };

        // 切换TOC目录展开收缩的相关操作.
        const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        
    });
</script>

    

</main>




    <footer class="page-footer bg-color">
    
    <div class="container row center-align" style="margin-bottom: 0px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            <span id="year">2019</span>
            <a href="/blog/about" target="_blank">glh</a>
            |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a>
            |&nbsp;Theme&nbsp;<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank">Matery</a>
            <br>
            
            
            
            
            
            
            <span id="busuanzi_container_site_pv">
                |&nbsp;<i class="far fa-eye"></i>&nbsp;总访问量:&nbsp;<span id="busuanzi_value_site_pv"
                    class="white-color"></span>&nbsp;次
            </span>
            
            
            <span id="busuanzi_container_site_uv">
                |&nbsp;<i class="fas fa-users"></i>&nbsp;总访问人数:&nbsp;<span id="busuanzi_value_site_uv"
                    class="white-color"></span>&nbsp;人
            </span>
            
            <br>
            
            <br>
            
        </div>
        <div class="col s12 m4 l4 social-link social-statis">
    <a href="https://github.com/sky508/blog.git" class="tooltipped" target="_blank" data-tooltip="访问我的GitHub" data-position="top" data-delay="50">
        <i class="fab fa-github"></i>
    </a>



    <a href="mailto:17730269920@163.com" class="tooltipped" target="_blank" data-tooltip="邮件联系我" data-position="top" data-delay="50">
        <i class="fas fa-envelope-open"></i>
    </a>







    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=978742791" class="tooltipped" target="_blank" data-tooltip="QQ联系我: 978742791" data-position="top" data-delay="50">
        <i class="fab fa-qq"></i>
    </a>







</div>
    </div>
</footer>



    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script src="/blog/js/search.js"></script>
<script type="text/javascript">
$(function () {
    searchFunc("/blog/search.xml", 'searchInput', 'searchResult');
});
</script>

    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="https://sky508.gitee.io/blog/libs/materialize/materialize.min.js"></script>
    <script src="https://sky508.gitee.io/blog/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="https://sky508.gitee.io/blog/libs/aos/aos.js"></script>
    <script src="https://sky508.gitee.io/blog/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="https://sky508.gitee.io/blog/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="/blog/js/matery.js"></script>

    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

    
    <script src="https://sky508.gitee.io/blog/libs/others/clicklove.js" async="async"></script>
    
    
    <script async src="https://sky508.gitee.io/blog/libs/others/busuanzi.pure.mini.js"></script>
    

    

    

    

    

    

    
    <script src="https://sky508.gitee.io/blog/libs/instantpage/instantpage.js" type="module"></script>
    

<script>
            window.imageLazyLoadSetting = {
                isSPA: false,
                processImages: null,
            };
        </script><script>window.addEventListener("load",function(){var t=/\.(gif|jpg|jpeg|tiff|png)$/i,r=/^data:image\/[a-z]+;base64,/;Array.prototype.slice.call(document.querySelectorAll("img[data-original]")).forEach(function(a){var e=a.parentNode;"A"===e.tagName&&(e.href.match(t)||e.href.match(r))&&(e.href=a.dataset.original)})});</script><script>!function(n){n.imageLazyLoadSetting.processImages=o;var i=n.imageLazyLoadSetting.isSPA,r=Array.prototype.slice.call(document.querySelectorAll("img[data-original]"));function o(){i&&(r=Array.prototype.slice.call(document.querySelectorAll("img[data-original]")));for(var t,e,a=0;a<r.length;a++)t=r[a],0<=(e=t.getBoundingClientRect()).bottom&&0<=e.left&&e.top<=(n.innerHeight||document.documentElement.clientHeight)&&function(){var t,e,n,i,o=r[a];t=o,e=function(){r=r.filter(function(t){return o!==t})},n=new Image,i=t.getAttribute("data-original"),n.onload=function(){t.src=i,e&&e()},n.src=i}()}o(),n.addEventListener("scroll",function(){var t,e;t=o,e=n,clearTimeout(t.tId),t.tId=setTimeout(function(){t.call(e)},500)})}(this);</script></body>

</html>
